package org.aaron.mp3player.service;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;
import java.util.Queue;

import org.aaron.mp3player.lrc.LrcProcessor;
import org.aaron.mp3player.model.Mp3Info;
import org.aaron.mp3player.utils.FileUtils;
import org.aaron.mp3player.utils.SystemConfig;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;

public class Mp3PlayerService extends Service {

	private MediaPlayer mediaPlayer = null;
	private boolean isPlaying = false;
	private boolean isReleased = false;

	private Handler handler = new Handler();
	private String message = null;
	private long begin = 0;
	private long nextTimeMill = 0;
	private long currentTimeMill = 0;
	private long pauseTimeMill = 0;
	private UpdateTimeCallback updateTimeCallback = null;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Mp3Info mp3Info = (Mp3Info) intent.getSerializableExtra("mp3info");
		int MSG = intent.getIntExtra("msg", 0);
		if (mp3Info != null) {
			if (SystemConfig.PLAYER_MESSAGE.MSG_PLAY == MSG) {
				play(mp3Info);
			}
			if (SystemConfig.PLAYER_MESSAGE.MSG_PAUSE == MSG) {
				pause();
			}
			if (SystemConfig.PLAYER_MESSAGE.MSG_STOP == MSG) {
				stop();
			}

		}
		return super.onStartCommand(intent, flags, startId);
	}

	private void play(Mp3Info mp3Info) {
		if (!isPlaying) {
			FileUtils fileUtils = new FileUtils();
			mediaPlayer = MediaPlayer.create(Mp3PlayerService.this, Uri.parse("file://" + fileUtils.queryLocalMp3Path(mp3Info.getMp3Name())));
			mediaPlayer.setLooping(false);
			mediaPlayer.start();
			prepareLrc(mp3Info.getLrcName());
			begin = System.currentTimeMillis();
			handler.postDelayed(updateTimeCallback, 5);
			isPlaying = true;
			isReleased = false;
		}
	}

	private void pause() {
		if (mediaPlayer != null && !isReleased) {
			if (isPlaying) {
				mediaPlayer.pause();
				handler.removeCallbacks(updateTimeCallback);
				pauseTimeMill = System.currentTimeMillis();
			} else {
				mediaPlayer.start();
				handler.postDelayed(updateTimeCallback, 5);
				begin = System.currentTimeMillis() - pauseTimeMill + begin;
			}
			isPlaying = isPlaying ? false : true;
		}
	}

	private void stop() {
		if (mediaPlayer != null && isPlaying) {
			if (!isReleased) {
				handler.removeCallbacks(updateTimeCallback);
				mediaPlayer.stop();
				mediaPlayer.release();
				isReleased = true;
			}
			isPlaying = false;
		}
	}

	private void prepareLrc(String lrcname) {
		try {
			FileUtils fileUtils = new FileUtils();
			InputStream inputStream = fileUtils.queryLocalMp3LrcPath(lrcname);
			LrcProcessor lrcProcessor = new LrcProcessor();
			List<Queue> queues = lrcProcessor.process(inputStream);
			updateTimeCallback = new UpdateTimeCallback(queues);
			begin = 0;
			currentTimeMill = 0;
			nextTimeMill = 0;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	class UpdateTimeCallback implements Runnable {
		List<Queue> queues;

		public UpdateTimeCallback(List<Queue> queues) {
			this.queues = queues;
		}

		@Override
		public void run() {
			Queue<Long> timeMills = queues.get(0);
			Queue<String> lrcs = queues.get(1);
			long offest = System.currentTimeMillis() - begin;
			if (currentTimeMill == 0) {
				nextTimeMill = (Long) timeMills.poll();
				message = (String) lrcs.poll();
			}
			if (offest >= nextTimeMill) {
				Intent intent=new Intent();
				intent.setAction(SystemConfig.ACTION.LRC_MESSAGE_ACTION);
				intent.putExtra("lrcmessage", message);
				Mp3PlayerService.this.sendBroadcast(intent);
				nextTimeMill = (Long) timeMills.poll();
				message = (String) lrcs.poll();
			}
			currentTimeMill += 10;
			handler.postDelayed(updateTimeCallback, 10);
		}
	}

}
